LIBRARY PrintF

>printf
; *******************************************************************
; Subroutine:   printf
; Description:  Incredibly simple printf
; Parameters:   as printf
;               r0-> format string
;               r1-r3 params
; Returns:      as printf
; *******************************************************************
   STMFD   (sp)!,{r1-r3}                 ; so that registers are in order
   MOV     r1,sp                         ; r1-> base of registers
   STMFD   (sp)!,{r2-r5,link}            ; Stack registers
   MOV     r2,r0                         ; r2-> format
$loop
   LDRB    r0,[r2],#1                    ; read byte and inc
   TEQ     r0,#0                         ; is it 0 ?
   BEQ     $exit                         ; if so, jump out
   TEQ     r0,#10                        ; is it 10 ?
   SWIEQ   "OS_NewLine"                  ; if so, print a newline
   BEQ     $loop                         ;        and get more
   TEQ     r0,#ASC("%")                  ; is it % ?
   SWINE   "OS_WriteC"                   ; if not, print it
   BNE     $loop                         ;         and go for more
   LDRB    r0,[r2],#1                    ; read byte and inc
   TEQ     r0,#ASC("i")                  ; integer
   BEQ     $showint                      ; if so, show it
   TEQ     r0,#ASC("s")                  ; string
   BEQ     $showstr                      ; and go for more
   TEQ     r0,#ASC("S")                  ; string - ctrl terminated
   BEQ     $showstrctrl                  ; and go for more
   TEQ     r0,#ASC("c")                  ; char
   BEQ     $showchar                     ; show it
   TEQ     r0,#ASC("x")                  ; hex number
   BEQ     $showhex                      ; show it
   SWI     "OS_WriteC"                   ; if unknown, just print it
   B       $loop

$showint
   LDR     r0,[r1],#4                    ; read value and inc
   REM     "%r0"
   B       $loop                         ; and go for more


$showhex
   LDR     r0,[r1],#4                    ; read value and inc
   REM     "%&0"
   B       $loop                         ; and go for more

$showstr
   LDR     r0,[r1],#4                    ; read value and inc
   SWI     "OS_Write0"                   ; write it
   B       $loop

$showchar
   LDR     r0,[r1],#4                    ; read value and inc
   SWI     "OS_WriteC"                   ; write it
   B       $loop

$showstrctrl
   LDR     r3,[r1],#4                    ; read pointer from stack
$ssc_loop
   LDRB    r0,[r3],#1                    ; read and inc
   CMP     r0,#32                        ; is it 'ok' ?
   SWIGE   "OS_WriteC"                   ; if so, write it
   BGE     $ssc_loop                     ; keep writing
   B       $loop                         ; and get more

$exit
   LDMFD   (sp)!,{r2-r5,link}            ; Restore registers
   ADD     sp,sp,#3*4                    ; skip r1-r3
   MOVS    pc,link                       ; return
